package by.pavlyukevich.paymentsystem.panel.card;

import javax.inject.Inject;
import javax.persistence.metamodel.SingularAttribute;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.datetime.markup.html.basic.DateLabel;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.springframework.orm.jpa.JpaSystemException;

import by.pavlyukevich.paymentsystem.add.AbstractDataProvider;
import by.pavlyukevich.paymentsystem.add.AdminAjaxLink;
import by.pavlyukevich.paymentsystem.add.ErrorEvent;
import by.pavlyukevich.paymentsystem.add.PanelUpdateEvent;
import by.pavlyukevich.paymentsystem.dataaccess.filter.CardLimitFilter;
import by.pavlyukevich.paymentsystem.dataaccess.filter.Filter;
import by.pavlyukevich.paymentsystem.datamodel.card.CardLimit;
import by.pavlyukevich.paymentsystem.datamodel.card.CardLimit_;
import by.pavlyukevich.paymentsystem.panel.MyPagingNavigator;
import by.pavlyukevich.paymentsystem.services.card.CardLimitService;

public class CardLimitListPanel extends Panel {

	@Inject
	private CardLimitService cardLimitService;
	private CardLimitFilter cardLimitFilter;
	private Panel respPanel;

	public CardLimitListPanel(String id) {
		this(id, new CardLimitFilter());
	}

	public CardLimitListPanel(String id, CardLimitFilter cardLimitFilter) {
		super(id);
		this.cardLimitFilter = cardLimitFilter;
		this.respPanel = this;
	}

	@Override
	protected void onInitialize() {
		setOutputMarkupId(true);

		CardLimitDataProvider cardLimitDP = new CardLimitDataProvider(CardLimit_.periodBegin,
				cardLimitFilter);

		final WebMarkupContainer cardLimitTable = new WebMarkupContainer("cardLimit-table");
		cardLimitTable.setOutputMarkupId(true);
		add(cardLimitTable);

		DataView<CardLimit> dataView = new DataView<CardLimit>("cardLimit-row", cardLimitDP, 20) {

			@Override
			protected void populateItem(Item<CardLimit> item) {

				final CardLimit cardLimit = item.getModelObject();

				item.add(DateLabel.forDatePattern("periodBegin", "dd.MM.yyyy"));
				item.add(DateLabel.forDatePattern("periodEnd", "dd.MM.yyyy"));
				item.add(new Label("limitType"));
				item.add(new Label("amount"));
				item.add(new Label("quantity"));

				AjaxLink<Void> cardLink = new AdminAjaxLink<Void>("card") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
								new CardEditPanel("ac-panel", cardLimit.getCard(), respPanel)));
					}
				};
				cardLink.setBody(new Model<String>(cardLimit.getCard().getCardNumber().toString()));
				item.add(cardLink);

				item.add(new CheckBox("block").setEnabled(false));

				item.add(new AjaxLink<Void>("delete") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						try {
							cardLimitService.delete(cardLimit);
							target.add(respPanel);
						} catch (JpaSystemException e) {
							error(new ResourceModel("t.error.unableToDelete").getObject());
							send(getPage(), Broadcast.BREADTH, new ErrorEvent(target));
						}

					}
				});

				item.add(new AjaxLink<Void>("edit") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
								new CardLimitEditPanel("ac-panel", cardLimit, respPanel)));
					}
				});
			}

		};

		cardLimitTable.add(dataView.setOutputMarkupId(true));
		add(new AjaxLink<Void>("new") {

			@Override
			public void onClick(AjaxRequestTarget target) {
				CardLimit cardLimit = new CardLimit();
				cardLimit.setCard(cardLimitFilter.getCard());
				send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
						new CardLimitEditPanel("ac-panel", cardLimit, respPanel)));
			}
		});

		add(new MyPagingNavigator("paging", dataView));

		add(new OrderByBorder<SingularAttribute<CardLimit, ?>>("sortByPeriodBegin",
				CardLimit_.periodBegin, cardLimitDP));
		add(new OrderByBorder<SingularAttribute<CardLimit, ?>>("sortByPeriodEnd",
				CardLimit_.periodEnd, cardLimitDP));
		add(new OrderByBorder<SingularAttribute<CardLimit, ?>>("sortByAmount", CardLimit_.amount,
				cardLimitDP));
		add(new OrderByBorder<SingularAttribute<CardLimit, ?>>("sortByQuantity",
				CardLimit_.quantity, cardLimitDP));

		super.onInitialize();
	}

	private class CardLimitDataProvider extends AbstractDataProvider<CardLimit> {
		public CardLimitDataProvider(SingularAttribute<CardLimit, ?> sortParam,
				Filter<CardLimit> filter) {
			super(sortParam, filter, cardLimitService);
		}
	};

}
